package your.rfgui.extgui.controller.tree;

import com.google.common.collect.Iterators;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.tree.TreeNode;
import org.apache.log4j.Logger;
import your.rfgui.extgui.controller.tree.data.LabelDataItem;
import your.rfgui.extgui.data.intf.DataItem;
import your.rfgui.extgui.data.intf.ViewNode;

/**
 * A view node representing a node in the tree GUI component
 */
public class TreeViewNode implements ViewNode, TreeNode {

   private static final Logger log = Logger.getLogger(TreeViewNode.class);
   /** data of this tree node */
   private DataItem dataItem;
   /** the parent view node */
   private TreeViewNode parent;
   /** the children nodes of this view node */
   private List<TreeViewNode> children = new ArrayList<TreeViewNode>();
   /** whether tree node shall be expanded in view, only used if rich:tree toggleType attribute set to ajax or server */
   private boolean expanded = false;

   /**
    * Create tree node holding a simple label data item
    */
   public TreeViewNode(String label) {
      this.dataItem = new LabelDataItem(label);
   }

   /**
    * Create tree node holding a simple label data item and connect to the given parent
    */
   public TreeViewNode(TreeViewNode parent, String label) {
      this(label);
      this.parent = parent;
      parent.addChildren(this);
   }

   /**
    * Create tree node associated with the given data item
    */
   public TreeViewNode(DataItem dataItem) {
      this.dataItem = dataItem;
   }

   /**
    * Create tree view node associated with the given data item and connect to the given parent
    */
   public TreeViewNode(TreeViewNode parent, DataItem dataItem) {
      this(dataItem);
      this.parent = parent;
      parent.addChildren(this);
   }

   /**
    * Get the data item of this view node
    */
   @Override
   public DataItem getDataItem() {
      return dataItem;
   }

   /**
    * Get the label of the associated data item
    */
   public String getLabel() {
      return dataItem.getLabel();
   }

   /**
    * Get the type of the view node, simply the type of the associated data item
    */
   public String getType() {
      return dataItem.getClass().getSimpleName();
   }

   /**
    * String for debug purposes
    */
   @Override
   public String toString() {
      return getLabel();
   }
   
   /**
    * expansion control
    */
   public boolean getExpanded() {
      log.info("getExpanded: " + expanded);
      return this.expanded;
   }

   public void setExpanded(boolean expanded) {
      log.info("setExpanded: " + expanded);
      this.expanded = expanded;
   }

   /**
    * implementation of TreeNode interface
    */
   public TreeViewNode getChildAt(int childIndex) {
      return children.get(childIndex);
   }

   public int getChildCount() {
      return children.size();
   }

   public TreeViewNode getParent() {
      return parent;
   }

   public int getIndex(TreeNode node) {
      return children.indexOf(node);
   }

   public boolean getAllowsChildren() {
      return true;
   }

   public boolean isLeaf() {
      return children.isEmpty();
   }

   public Enumeration<TreeViewNode> children() {
      return Iterators.asEnumeration(children.iterator());
   }

   private void addChildren(TreeViewNode child) {
      children.add(child);
   }
}
